using MWTools.Client.Common;
using Office = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Reflection;
using System.Windows.Forms;
using MWTools.Client.UI;
using MWTools.Client;
using Word = Microsoft.Office.Interop.Word;

namespace MWTools.Client
{
    using System;
    using Extensibility;
    using System.Runtime.InteropServices;

    #region Read me for Add-in installation and setup information.
    // When run, the Add-in wizard prepared the registry for the Add-in.
    // At a later time, if the Add-in becomes unavailable for reasons such as:
    //   1) You moved this project to a computer other than which is was originally created on.
    //   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
    //   3) Registry corruption.
    // you will need to re-register the Add-in by building the MWToolsOfficeHelperSetup project, 
    // right click the project in the Solution Explorer, then choose install.
    #endregion

    /// <summary>
    ///   The object for implementing an Add-in.
    /// </summary>
    /// <seealso class='IDTExtensibility2' />
    [GuidAttribute("0D259B09-F32E-495D-972B-E2615A22F710"), ProgId("MWToolsOfficeHelper.Connect")]
    public class Connect : Object, Extensibility.IDTExtensibility2
    {

        private Office.CommandBarButton _commandButton;
        private Outlook.Application _outlookApplication;
        private Word.Application _wordApplication;
        private Office.COMAddIn _addInInstance;
        private Outlook.Inspectors _inspectors = null;
        Office.CommandBar _commandBar;
        bool isOutlook = false;

        private MWTools.Client.ControllerBase _controller = null;

        #region Add-In Events
        /// <summary>
        ///		Implements the constructor for the Add-in object.
        ///		Place your initialization code within this method.
        /// </summary>
        public Connect()
        {
            Logger.DebugFormat("Connect.Connect", "");

        }

        /// <summary>
        ///      Implements the OnConnection method of the IDTExtensibility2 interface.
        ///      Receives notification that the Add-in is being loaded.
        /// </summary>
        /// <param term='application'>
        ///      Root object of the host application.
        /// </param>
        /// <param term='connectMode'>
        ///      Describes how the Add-in is being loaded.
        /// </param>
        /// <param term='addInInst'>
        ///      Object representing this Add-in.
        /// </param>
        /// <seealso class='IDTExtensibility2' />
        public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
        {
            Logger.DebugFormat("Connect.OnConnection", "");


            if (application is Outlook.Application)
            {
                isOutlook = true;
                Logger.DebugFormat("Connect.OnConnection", "in outlook");
                _outlookApplication = (Outlook.Application)application;
                _inspectors = _outlookApplication.Inspectors;
                _outlookApplication.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(_application_ItemContextMenuDisplay);

            }

            if (application is Word.Application)
            {
                Logger.DebugFormat("Connect.OnConnection", "in word");
                _wordApplication = (Word.Application)application;
            }
            addInInstance = addInInst;
        }

        /// <summary>
        ///     Implements the OnDisconnection method of the IDTExtensibility2 interface.
        ///     Receives notification that the Add-in is being unloaded.
        /// </summary>
        /// <param term='disconnectMode'>
        ///      Describes how the Add-in is being unloaded.
        /// </param>
        /// <param term='custom'>
        ///      Array of parameters that are host application specific.
        /// </param>
        /// <seealso class='IDTExtensibility2' />
        public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
        {
        }

        /// <summary>
        ///      Implements the OnAddInsUpdate method of the IDTExtensibility2 interface.
        ///      Receives notification that the collection of Add-ins has changed.
        /// </summary>
        /// <param term='custom'>
        ///      Array of parameters that are host application specific.
        /// </param>
        /// <seealso class='IDTExtensibility2' />
        public void OnAddInsUpdate(ref System.Array custom)
        {
        }

        /// <summary>
        ///      Implements the OnStartupComplete method of the IDTExtensibility2 interface.
        ///      Receives notification that the host application has completed loading.
        /// </summary>
        /// <param term='custom'>
        ///      Array of parameters that are host application specific.
        /// </param>
        /// <seealso class='IDTExtensibility2' />
        public void OnStartupComplete(ref System.Array custom)
        {
            object application = null;
            if (_outlookApplication == null)
                createButtonControlForWord();
            else
                createButtonControlForOutlook(_outlookApplication);

        }

        private void createButtonControlForWord()
        {
            Office.CommandBars oCommandBars = null;
            Office.CommandBar oStandardBar;

            try
            {
                oCommandBars = (Office.CommandBars)_wordApplication.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty, null, _wordApplication, null);
            }
            catch (Exception)
            {
                // Outlook has the CommandBars collection on the Explorer object.
                object oActiveExplorer;
                oActiveExplorer = _wordApplication.GetType().InvokeMember("ActiveExplorer",
                                      BindingFlags.GetProperty,
                                      null,
                                      _wordApplication,
                                      null);
            }

            // Set up a custom button on the "Standard" commandbar.
            try
            {
                oStandardBar = oCommandBars["Standard"];
            }
            catch (Exception)
            {
                // Access names its main toolbar Database.
                oStandardBar = oCommandBars["Database"];
            }

            // In case the button was not deleted, use the exiting one.
            try
            {
                _commandButton = (Office.CommandBarButton)oStandardBar.Controls["Submit"];
            }
            catch (Exception)
            {
                object omissing = System.Reflection.Missing.Value;
                _commandButton = (Office.CommandBarButton)oStandardBar.Controls.Add(Microsoft.Office.Core.MsoControlType.msoControlButton,
                                                              omissing,
                                                              omissing,
                                                              omissing,
                                                              true);
                _commandButton.Caption = "Submit";
                _commandButton.Style = Office.MsoButtonStyle.msoButtonCaption;
            }

            // The following items are optional, but recommended. 
            //The Tag property lets you quickly find the control 
            //and helps MSO keep track of it when more than
            //one application window is visible. The property is required
            //by some Office applications and should be provided.
            _commandButton.Tag = "MWTools - Export Document";
            _commandButton.FaceId = 3804;
            _commandButton.Style = Office.MsoButtonStyle.msoButtonIconAndCaption;
            // The OnAction property is optional but recommended. 
            //It should be set to the ProgID of the add-in, so that if
            //the add-in is not loaded when a user presses the button,
            //MSO loads the add-in automatically and then raises
            //the Click event for the add-in to handle. 
            _commandButton.OnAction = "0D259B09-F32E-495D-972B-E2615A22F710";

            _commandButton.Visible = true;
            _commandButton.Click +=new Office._CommandBarButtonEvents_ClickEventHandler(wordButton_click);
            object oName = _wordApplication.GetType().InvokeMember("Name",
                               BindingFlags.GetProperty,
                               null,
                               _wordApplication,
                               null);


            oStandardBar = null;
            oCommandBars = null;
        }
        private void createButtonControlForOutlook(object applicationObject)
        {
            Office.CommandBars oCommandBars = null;
            Office.CommandBar oStandardBar = null;

            try
            {
                oCommandBars = (Office.CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty, null, _outlookApplication, null);
            }
            catch (Exception)
            {
                if (isOutlook)
                {
                    // Outlook has the CommandBars collection on the Explorer object.
                    object oActiveExplorer;
                    oActiveExplorer = applicationObject.GetType().InvokeMember("ActiveExplorer",
                                          BindingFlags.GetProperty,
                                          null,
                                          applicationObject,
                                          null);
                    oCommandBars = (Office.CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",
                                                           BindingFlags.GetProperty,
                                                           null,
                                                           oActiveExplorer,
                                                           null);
                }
                else
                {
                    oCommandBars = (Office.CommandBars)applicationObject.GetType().InvokeMember("CommandBars",
                                       BindingFlags.GetProperty,
                                       null,
                                       applicationObject,
                                       null);
                }

            }

            // Set up a custom button on the "Standard" commandbar.
            try
            {
                oStandardBar = oCommandBars["Standard"];
            }
            catch (Exception)
            {
                if (isOutlook)
                    oStandardBar = oCommandBars["Database"];
            }

            // In case the button was not deleted, use the exiting one.
            string controlName = "MWTools";
            try
            {
                _commandButton = (Office.CommandBarButton)oStandardBar.Controls[controlName];
            }
            catch (Exception)
            {
                object omissing = System.Reflection.Missing.Value;
                _commandButton = (Office.CommandBarButton)oStandardBar.Controls.Add(Type.Missing,
                                                              omissing,
                                                              omissing,
                                                              omissing,
                                                              true);
                _commandButton.Caption = "";
                
                _commandButton.Style = Office.MsoButtonStyle.msoButtonCaption;
            }

            // The following items are optional, but recommended. 
            //The Tag property lets you quickly find the control 
            //and helps MSO keep track of it when more than
            //one application window is visible. The property is required
            //by some Office applications and should be provided.
            _commandButton.Tag = "Options";
            _commandButton.FaceId = 3804;
            // The OnAction property is optional but recommended. 
            //It should be set to the ProgID of the add-in, so that if
            //the add-in is not loaded when a user presses the button,
            //MSO loads the add-in automatically and then raises
            //the Click event for the add-in to handle. 
            _commandButton.OnAction = "0D259B09-F32E-495D-972B-E2615A22F710";
            _commandButton.Style = Office.MsoButtonStyle.msoButtonIconAndCaption;
            _commandButton.Visible = true;
            _commandButton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(this.outlookButton_click);
            object oName = applicationObject.GetType().InvokeMember("Name",
                               BindingFlags.GetProperty,
                               null,
                               applicationObject,
                               null);


            oStandardBar = null;
            oCommandBars = null;
        }

        void wordButton_click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            showOptions();
            FrmProgress frmProgress = new FrmProgress();
            try
            {
                frmProgress.Show();

                using (ControllerBase controller = new WordController())
                {
                    controller.SubmitItem(this._wordApplication.ActiveDocument);
                }

            }
            catch (Exception ex)
            {
                Logger.DebugFormat("Connect.contextMenu_click", ex.ToString());


                MessageBox.Show(ex.ToString());
            }
            finally
            {
                frmProgress.Close();
                frmProgress = null;
            }
        }

        private static bool showOptions()
        {
            FrmOptions frmOptions = new FrmOptions();
            DialogResult showDialog = frmOptions.ShowDialog();

            if (showDialog == DialogResult.OK)
            {
                
                return true;
            }

            return false;
        }

        void outlookButton_click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if(showOptions())
                MessageBox.Show("Settings Saved!");
        }

        void _application_ItemContextMenuDisplay(Office.CommandBar CommandBar, Outlook.Selection Selection)
        {
            _commandBar = CommandBar;
            Office.CommandBarButton commandBarButton = _commandBar.Controls.Add(Type.Missing, 
                                                           Type.Missing, 
                                                           Type.Missing, 
                                                           Type.Missing, 
                                                           true) as Office.CommandBarButton;

            commandBarButton.FaceId = 3804;
            commandBarButton.Caption = "Send To Wiki";
            commandBarButton.Tag = "Send to Wiki";
            commandBarButton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(contextMenu_click);
        }

        void contextMenu_click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            Outlook.Inspector activeInspector = _outlookApplication.ActiveInspector();

            try
            {
                if (_outlookApplication.ActiveExplorer().Selection != null && _outlookApplication.ActiveExplorer().Selection.Count > 0)
                {
                    foreach (var item in _outlookApplication.ActiveExplorer().Selection)
                    {
                        //if (!(item is Outlook.MailItem))
                        //    MessageBox.Show("Sorry, only export of emails is currently supported");

                        Logger.DebugFormat("Connect._commandButton_Click", "processing item {0}", item.ToString());
                        
                            FrmProgress frmProgress = new FrmProgress();

                        try
                        {
                            frmProgress.Show();

                            using (OutlookController controller = new OutlookController())
                            {
                                controller.SubmitItem(item);
                            }

                        }
                        catch (Exception ex)
                        {
                            Logger.DebugFormat("Connect.contextMenu_click", ex.ToString());


                            MessageBox.Show(ex.ToString());
                        }
                        finally
                        {
                            frmProgress.Close();
                            frmProgress = null;
                        }

             
                    }


                }
            }
            catch (Exception ex)
            {
                Logger.Error("Connect._commandButton_Click", ex);
                MessageBox.Show(ex.ToString());

            }


        }


        /// <summary>
        ///      Implements the OnBeginShutdown method of the IDTExtensibility2 interface.
        ///      Receives notification that the host application is being unloaded.
        /// </summary>
        /// <param term='custom'>
        ///      Array of parameters that are host application specific.
        /// </param>
        /// <seealso class='IDTExtensibility2' />
        public void OnBeginShutdown(ref System.Array custom)
        {
            Logger.DebugFormat("Connect.OnBeginShutdown", "");
        }


        #endregion

        private object addInInstance;
    }
}